/***
 * Copyright (C) 2013 Peng fei Pan <sky@xiaopan.me>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.tusuo.stds.util.webview;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Color;
import android.os.Build;
import android.support.compat.BuildConfig;
import android.webkit.WebSettings;
import android.webkit.WebView;

import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.google.gson.Gson;
import com.tusuo.stds.rest.Question;
import com.tusuo.stds.ui.complete.CompleteQuestionActivity_;
import com.tusuo.stds.ui.question.QuestionActivity_;
import com.tusuo.stds.ui.similarity.SimilarityTempActivity_;
import com.tusuo.stds.util.Utils;

import java.lang.reflect.Field;


/**
 * WebView管理器，提供常用设置
 */
public class WebViewManager {
    private Activity mActivity;

    private BridgeWebView mWebView;
    private WebSettings mWebSettings;

    public WebViewManager(Activity activity,
                          BridgeWebView webView){
        mActivity = activity;
        mWebView = webView;
        mWebSettings = mWebView.getSettings();
    }

    public void setWebView(BridgeWebView webView) {
        mWebView = webView;
    }

    public void init() {
        enableJavaScript();
        enableJavaScriptOpenWindowsAutomatically();
        disableZoom();
        enableAdaptive();

        if(Build.VERSION.SDK_INT >= 19) {
            mWebSettings.setLoadsImagesAutomatically(true);
        } else {
            mWebSettings.setLoadsImagesAutomatically(true);
        }

        mWebSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
//        mWebSettings.setPluginsEnabled(true);
        mWebSettings.setPluginState(WebSettings.PluginState.ON);
        mWebSettings.setAllowFileAccess(true);
        mWebSettings.setDefaultTextEncodingName("UTF-8");
        mWebSettings.setDomStorageEnabled(true);
        mWebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        mWebSettings.setDatabaseEnabled(false);
        // 取消网页记住密码
        mWebSettings.setSavePassword(false);
        mWebSettings.setSaveFormData(false);
        mWebSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        if (Build.VERSION.SDK_INT >= 21) {
            mWebSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

        mWebView.clearFormData();
        mWebView.clearHistory();
//        mWebView.clearCache(true);
        mWebView.setHorizontalScrollBarEnabled(false);
        mWebView.setVerticalScrollBarEnabled(false);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            mWebView.setBackgroundColor(Color.argb(1, 0, 0, 0));

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//            if (0 != (mActivity.getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE)) {
                WebView.setWebContentsDebuggingEnabled(true);
//            }
        }

    }

    /**
     * 开启自适应功能
     */
    public WebViewManager enableAdaptive(){
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setLoadWithOverviewMode(true);
        return this;
    }

    /**
     * 禁用自适应功能
     */
    public WebViewManager disableAdaptive(){
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setLoadWithOverviewMode(true);
        return this;
    }

    /**
     * 开启缩放功能
     */
    public WebViewManager enableZoom(){
        mWebSettings.setSupportZoom(true);
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setBuiltInZoomControls(true);
        return this;
    }

    /**
     * 禁用缩放功能
     */
    public WebViewManager disableZoom(){
        mWebSettings.setSupportZoom(false);
        mWebSettings.setUseWideViewPort(false);
        mWebSettings.setBuiltInZoomControls(false);
        return this;
    }

    /**
     * 开启JavaScript
     */
    @SuppressLint("SetJavaScriptEnabled")
    public WebViewManager enableJavaScript(){
        mWebSettings.setJavaScriptEnabled(true);
        return this;
    }

    /**
     * 禁用JavaScript
     */
    public WebViewManager disableJavaScript(){
        mWebSettings.setJavaScriptEnabled(false);
        return this;
    }

    /**
     * 开启JavaScript自动弹窗
     */
    public WebViewManager enableJavaScriptOpenWindowsAutomatically(){
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        return this;
    }

    /**
     * 禁用JavaScript自动弹窗
     */
    public WebViewManager disableJavaScriptOpenWindowsAutomatically(){
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(false);
        return this;
    }

    /**
     * 返回
     * @return true：已经返回，false：到头了没法返回了
     */
    public boolean goBack(){
        // 检查历史记录里的url是否正确,当遇到无效的页面或空白页时，清空历史记录
        for (int i = 0;i < mWebView.copyBackForwardList().getSize();i ++) {
            if (isValidUrl(mWebView.copyBackForwardList().getItemAtIndex(i).getUrl())) {
                mWebView.clearHistory();
            }
        }

        // 检查当前url是否正确
        if(!isValidUrl(mWebView.getUrl())) {
            mWebView.clearHistory();
        }

        if (mWebView.canGoBack()) {
            mWebView.goBack();
            return true;
        } else {
            return false;
        }
    }

    public void reload() {
        if (!Utils.Network.isNetworkAvailable()) {
//            Utils.UI.showToastShort("网络不可用！请检查网络设置后重启应用。");
        } else {
            if (mWebView != null) {
                mWebView.reload();
            }
        }
    }

    public void clearHistory() {
        mWebView.clearHistory();
    }

    /**
     *
     * @param url
     * @return
     */
    public boolean isValidUrl(String url) {
        return (url != null && url.startsWith("http"));
    }

    public void loadUrl(String url) {
        mWebView.setWebViewClient(new FindWebViewClient(mWebView, mActivity));

        mWebView.setWebChromeClient(new CustomWebChromeClient(mActivity));

//        CookieHelper.setWebViewRequestUrlCookie(mActivity, url, mCurrentUser.getCurrentCookie());

//        Map<String, String> cookies = new WeakHashMap<>();
//        cookies.put("AppOS", "Android");

//        if (!url.startsWith("javascript")) {
//            mWebView.clearView();
//        }
//        mWebView.loadUrl(url, cookies);
        mWebView.loadUrl(url);
    }

    public void registerHandlerSubmitAnswer(BridgeHandler callback) {
        mWebView.registerHandler("APP.SubmitAnswer", callback);
    }

    public void registerHandlerShare(BridgeHandler callback) {
        mWebView.registerHandler("APP.share",callback);
    }

    public void initQuestion(Question question) {
        mWebView.callHandler("WEB.initQuestion", new Gson().toJson(question), new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                if (mActivity instanceof QuestionActivity_) {
                    ((QuestionActivity_)mActivity).setLastTime();
                }else if (mActivity instanceof SimilarityTempActivity_) {
                    ((SimilarityTempActivity_)mActivity).setLastTime();
                }else if (mActivity instanceof CompleteQuestionActivity_) {
                    ((CompleteQuestionActivity_)mActivity).setLastTime();
                }
            }
        });
    }

    public void setReviewMode() {
        mWebView.callHandler("WEB.setType", "review", new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                System.out.println("data+++++++" + data);
            }
        });
    }

    public void setAnswerMode() {
        mWebView.callHandler("WEB.setType", "normal", new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
                System.out.println("data+++++++" + data);
            }
        });
    }

    public void setShareParams() {
        mWebView.callHandler("WEB.share","",new CallBackFunction() {
            @Override
            public void onCallBack(String data) {
            }
        });
    }

    public void resume() {
        mWebView.onResume();
        enableJavaScript();
    }

    public void pause() {
        mWebView.onPause();
    }

    public void stop() {
        mWebView.stopLoading();
        disableJavaScript();
    }

    public void destroy() {
        mWebSettings = null;
        if (mWebView != null) {
            mWebView.stopLoading();
            mWebView.clearCache(true);
            mWebView.clearHistory();
            mWebView.removeAllViews();
            // 释放资源
            mWebView.destroy();
            mWebView = null;
        }

        mActivity = null;
    }

    public String getTitle() {
        return mWebView.getTitle();
    }

    public void releaseAllWebViewCallback() {
        if (Build.VERSION.SDK_INT < 16) {
            try {
                Field field = WebView.class.getDeclaredField("mWebViewCore");
                field = field.getType().getDeclaredField("mBrowserFrame");
                field = field.getType().getDeclaredField("sConfigCallback");
                field.setAccessible(true);
                field.set(null, null);
            } catch (NoSuchFieldException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
            } catch (IllegalAccessException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                Field sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
                if (sConfigCallback != null) {
                    sConfigCallback.setAccessible(true);
                    sConfigCallback.set(null, null);
                }
            } catch (NoSuchFieldException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
            } catch (IllegalAccessException e) {
                if (BuildConfig.DEBUG) {
                    e.printStackTrace();
                }
            }
        }
    }
}
